package edu.scau.system.filter;

import cn.hutool.json.JSONUtil;
import edu.scau.core.constants.AjaxResult;
import edu.scau.core.constants.HttpStatus;
import edu.scau.core.util.ServletUtils;
import edu.scau.system.domain.LoginUser;
import edu.scau.system.service.TokenService;
import edu.scau.system.util.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * token过滤器 验证token有效性
 */
@Component("misAuthenticationTokenFilter")
public class MisAuthenticationTokenFilter extends OncePerRequestFilter {
    @Autowired
    private TokenService tokenService;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        //token过期存在nullpoint异常
        LoginUser loginUser = tokenService.getLoginUser(request);
        String token = request.getHeader("Authorization");
        if(loginUser != null && SecurityUtils.getAuthentication() == null) {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            // 如果认证过期，抛出CredentialsExpiredException
            if(loginUser.getExpireTime() < System.currentTimeMillis()) {
                // Token 过期
                String result = JSONUtil.toJsonStr(AjaxResult.error(HttpStatus.UNAUTHORIZED,"用户认证有效期已过，请重新登录"));
                ServletUtils.renderString(HttpStatus.FORBIDDEN,response,result);
                throw new CredentialsExpiredException("用户认证有效期已过，请重新登录");
            }

        }
        chain.doFilter(request, response);
    }
}
